/******************************************************************************
** 
** File name:	UTEST_20.c
**	
** Description: RTOS Unit Tests. Basic RTOS EVENT services unit test.
**				This test checks basic RTOS event SET/CLEAR/TEST services 
**				when its are called from task level.
**
** RTOS API functions to be tested:
**		
**	- rtos_event_set
**  - rtos_event_reset()
**  - rtos_event_test()
**
** Note:		<< Put all additional information that should be considered 
**				by RTOS developer or tester >>
**
*******************************************************************************
** Change history:
**
** 03/21/2012 - AK - File created. 
** 
******************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "rtos.h"
#include "utest.h"

/******************************************************************************
**	RTOS DECLARARTION SECTION
**
**  Standard config for RTOS task functionality testing.
**
**	Timer interrupt #1:	SYSTEM_TimerHandler (priority 0, defined by USER)
**
**	Timers:				n/a
**	Events:				evt0,		evt1,		evt2,		evt3
**	Messages:			n/a			
**	Queues:				n/a			
**	Timers:				n/a
**	
**	Three tasks:		tsk0,		tsk1,		tsk2,		tsk3 
**  Three priorities:	0(highest)	1 (high)	2 (middle)	3 (low)
**  Stack size:			8			20			20			20
**
**  Notes:				none
**
******************************************************************************/

RTOS_DECLARE_ISR(SYSTEM_TIMER_VECTOR,SYSTEM_TimerHandler);

RTOS_DECLARE_TASK(tsk0,  8, 0);
RTOS_DECLARE_TASK(tsk1, 20, 1);
RTOS_DECLARE_TASK(tsk2, 20, 2);
RTOS_DECLARE_TASK(tsk3, 20, 3);

RTOS_DECLARE_EVENT(evt0);
RTOS_DECLARE_EVENT(evt1);
RTOS_DECLARE_EVENT(evt2);
RTOS_DECLARE_EVENT(evt3);

/******************************************************************************
** Timer Hardware Configuration Section
******************************************************************************/
UTST_TIMER_t	sys_tmr = 
{
	&(SYSTEM_TIMER),
	20000,
	LEVEL_HIGH,
	STATE_STOP
};

/******************************************************************************
**	UNIT TEST MAIN FUNCTION
******************************************************************************/
int main(void)
{
	// RTOS kernel initialization
    rtos_initialize_os(0);

	// TBD - UTEST peripheral modules initialization (HW depended)

	// Timer-counters initialization (interrupt sources)
	// System timer is used for stack consistency verification
	utst_init_timer(&sys_tmr);		

	// Interrupt controller initialization
	utst_init_pmic();

	// RTOS task initialization 	
    rtos_task_init_exp (tsk0);	// Init but not start 
    rtos_task_init_exp (tsk1);
    rtos_task_init_exp (tsk2);
    rtos_task_start_exp(tsk3);
	
	// UTEST timers start
	UTST_TIMER_START(SYSTEM_TIMER);

	rtos_start_os();
	
	return 1;
}

/******************************************************************************
**	UNIT TEST INTERRUPT HANDLER[s]
******************************************************************************/

/* SYSTEM Timer - checks consistency of the task's stacks */
RTOS_ISR_FUNC(SYSTEM_TimerHandler)
{
	// Check task' stacks consistency
	rtos_stack_check(tsk0);
	rtos_stack_check(tsk1);
	rtos_stack_check(tsk2);
	rtos_stack_check(tsk3);	
}

/******************************************************************************
	UNIT TEST TASK FUNCTION[s]
******************************************************************************/

/* RTOS Task #0 */
RTOS_TASK_FUNC(tsk0)
{	
	while(1)
	{
		rtos_event_set(&evt3);
		rtos_task_suspend(&tsk0PID);
	}
}


/* RTOS Task #1 */
RTOS_TASK_FUNC(tsk1)
{
	while(1)
	{
		rtos_event_reset(&evt3);
		rtos_task_suspend(&tsk1PID);
	}
}

/* RTOS Task #2 */
RTOS_TASK_FUNC(tsk2)
{
	while(1)
	{
		if (rtos_event_test(&evt3) == EVT_WAIT)
		{
			rtos_halt_os();
		}
		rtos_task_suspend(&tsk2PID);
	}
}

/* RTOS Task #3 */
RTOS_TASK_FUNC(tsk3)
{
	RTOS_EST_t	state;

	while(1)
	{
		state = rtos_event_test(&evt3);
		switch (state)
		{
			case EVT_PEND:
				rtos_task_resume(&tsk0PID);
				break;
			case EVT_DONE:
				rtos_event_set(&evt3);
				rtos_task_resume(&tsk1PID);
				break;
			case EVT_WAIT:
				rtos_task_resume(&tsk2PID);
				break;
			default:
				rtos_halt_os();
		}
	}
}

